Skip to content

docs(spec): name every accepted key in the two action convention docblocks - #16246

Merged
huangyiirene merged 1 commit into
mainfrom
claude/issue-14708-actions-convention-docblock-keys
Sep 6, 2026
Merged

docs(spec): name every accepted key in the two action convention docblocks#16246
huangyiirene merged 1 commit into
mainfrom
claude/issue-14708-actions-convention-docblock-keys

Conversation

@huangyiirene

Copy link
Copy Markdown
Collaborator

Fixes #14708

_actions and globalActions are built from one factory, actionTranslationSchema(...) — the file says so outright, "Shared by object _actions and globalActions" — so their hand-written convention lists carried the identical four addresses and the identical two omissions. An author reading either list to learn which keys exist saw a strict subset of what the schema has accepted all along.

Placeholders below are written as bare words (OBJECT / ACTION / PARAM / VALUE) because the body sanitizer eats angle-bracket fragments. The file itself keeps its own angle-bracket spelling, unchanged.

What changed

Ten added comment lines in one file, packages/spec/src/system/translation.zod.ts, plus a changeset. Both lists now name, in the factory's declaration order and in the spelling already landed in i18n-resolver.ts's own file header (PR #14707):

  • description, after label
  • params.PARAM.label, .helpText, .placeholder, .options.VALUE, before resultDialog.*

Nothing else. No schema, no factory, no resolver. resultDialog.* keeps its position and its wildcard — its leaves are enumerated at ActionResultDialogTranslationSchema's own docblock, which is the file's existing convention for a nested sub-schema that documents itself.

Both sites were re-located by pattern, not by the line numbers in the card or the claim comment; both of those had already rotted.

Does this move the contract? No — measured, not assumed

The keys were already declared and already accepted, so nothing about what a bundle validates to moves. The one measurable precondition on that verdict is whether the text projects into a generated artifact. It does not, and the control was reproduced on this file's own generated page, content/docs/references/system/translation.mdx:

probe occurrences
lit control — the .describe() string "Action translations keyed by action name" 3
lit control — the .describe() string "Global action translations keyed by action name" 2
docblock prose — "Convention (auto-resolved by" 0
docblock prose — "Action translations keyed by action name (snake_case)" 0
docblock prose — "Global (object-less) action translations keyed by action name (snake_case)" 0
the two address rows themselves (confirmText, successMessage) 0

The third and fourth rows are the sharp pair: the .describe() string is a prefix of the docblock's opening sentence, so the same words score 3 as a describe string and 0 the moment the docblock-only suffix is included. .describe() reaches the page; the docblock does not.

Mechanically confirmed: pnpm --filter @objectstack/spec check:generated reports all 15 checked-in generated artifacts up to date after the edit — check:docs, check:api-surface, check:authorable-surface and the rest — so zero regeneration is owed.

Where the text does land, which is why a changeset is owed. packages/spec publishes src/**/*.zod.ts through its package.json files array, and the build output preserves JSDoc: 9 of 22 emitted .js chunks and 1 of 64 emitted declaration files carry the new lines. All three are comment positions, and check:api-surface is green, so no export signature moved. Documentation-only, patch.

Verification

Run at a6879f8b6, the branch tip.

check result
pnpm --filter @objectstack/spec build exit 0, 34/34 declaration files present
pnpm --filter @objectstack/spec check:generated 15/15 artifacts up to date
pnpm --filter @objectstack/spec typecheck exit 0 (tsc --noEmit, check:scripts-typecheck, check:test-typecheck)
targeted vitest (translation, translation-typegen, i18n-resolver, action, action-description) 5 files / 538 tests passed
gate families derived by scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack 67 of 68 run, all green; reconciled with --ran
pnpm check:nul-bytes exit 0
full-repo eslint . --no-inline-config --format json 6196 files, 0 errors, 0 warnings, 64s

check:i18n-walk-parity is the family most directly about this file: green, "11 declared group(s), 8 walked, 3 exempted — every declared group has an extractor face."

Two gates first returned PREREQUISITE NOT MET and were read as NOT MEASURED rather than as findings — check:doc-formula-expressions (exit 3, unbuilt @objectstack/formula and @objectstack/lint) and check:i18n-walk-parity (exit 1, unbuilt @objectstack/cli). Both prerequisites were built and both gates re-run green; the numbers above are the re-runs. Every exit code was captured before any pipe.

Declared narrowings, both handed to CI:

  • pnpm check:dual-build-cjs-loads — the one derived family not run. Its prerequisite is a whole-repo pnpm build; it named 86 unbuilt packages and measured nothing. This diff changes no exports map, no package manifest and no emitted module format.
  • Package tests. turbo ls --affected against the merge base lists roughly 45 packages, all downstream of @objectstack/spec and all reached only through its build output. Ran the five translation and action test files rather than all 482 spec test files or any downstream package.

The lint reading needed no narrowing at all: the full population, 6196 files as counted by eslint itself, was linted.

Not in scope

Triage names the mechanism behind this card: both lists are hand-maintained prose copies of what one factory declares, and nothing binds them, which makes the docblocks a fourth consumer of one declaration alongside the resolver and the i18n extractor. That class belongs to #14653, which is untouched by this PR and stays open. Out-of-scope findings from this run: none.


Generated by Claude Code

…locks

`_actions` and `globalActions` are built from one factory,
`actionTranslationSchema(...)`, so their hand-written convention lists carried
the identical four addresses and the identical two omissions: `description` and
`params.<param_name>.{label, helpText, placeholder, options}` were declared and
accepted by the schema but named by neither list.

Both lists now enumerate them, in the factory's declaration order and in the
spelling already landed in `i18n-resolver.ts`'s own header. Prose only — no
schema, factory or resolver is touched, and nothing about what a bundle
validates to moves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
@github-actions github-actions Bot added the size/s label Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to listnot a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • the SDK route bridge reached 61 of 219 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 130 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json e270ebb791d6a1eb17f4c494b83077bb1f157f57packageMentionDocs.

Which tree this was computed on

This run read content/docs from c307cd52557e8f404458b89706b4675217284d3f — the merge of head a6879f8b6447b460626570357c34639df163ac8e into base e270ebb791d6a1eb17f4c494b83077bb1f157f57, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin c307cd52557e8f404458b89706b4675217284d3f && git checkout c307cd52557e8f404458b89706b4675217284d3f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e270ebb791d6a1eb17f4c494b83077bb1f157f57 a6879f8b6447b460626570357c34639df163ac8e && git checkout -B drift-repro e270ebb791d6a1eb17f4c494b83077bb1f157f57 && git merge --no-ff a6879f8b6447b460626570357c34639df163ac8e

node scripts/docs-audit/affected-docs.mjs --json e270ebb791d6a1eb17f4c494b83077bb1f157f57

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system tooling labels Sep 6, 2026
@huangyiirene
huangyiirene marked this pull request as ready for review September 6, 2026 11:15
@huangyiirene
huangyiirene added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit 99261a7 Sep 6, 2026
35 of 36 checks passed
@huangyiirene
huangyiirene deleted the claude/issue-14708-actions-convention-docblock-keys branch September 6, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:system size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

translation.zod's _actions convention docblock omits description and params.*, which the same schema declares

2 participants